
#ifndef APP_DEVICE_H
#define APP_DEVICE_H

#include "stdint.h"
#include "board.h"
#include "resource.h"
#include "pid.h"

/* 数据存储地址 */
#define DEVICE_STORE_ADDR       (0)
#define DEVICE_FACTOR_ADDR      (2048)

#define DEVICE_METER_BUFF_SIZE      (4)
#define DEVICE_FACTOR_MAP_NUM       (22)
#define DEVICE_FACTOR_PID_NUM       (10)
#define DEVICE_SHORTKEY_NUM         (5)
#pragma pack(1)

enum
{
    kDeviceWork_Stop = 0,
    kDeviceWork_Enable,
    kDeviceWork_Sleep,
};

typedef struct
{   
    float value;
    int32_t adc;
}map_para_t;

typedef struct
{   
    __IO float value;
    __IO float value_ins; //瞬时值
    __IO float value_buff[DEVICE_METER_BUFF_SIZE];
    __IO float value_total;
    int32_t adc;
    //__IO float value_max;
    uint8_t cnt;
    uint8_t map_offset;
    uint8_t pid_offset;
    map_para_t *map;
    pid_para_t *pid;
    uint8_t invalid;
    uint8_t id;
}device_meter_t;

typedef union
{
    struct
    {
        device_meter_t power_v;
        device_meter_t power_i;
        device_meter_t power_p;
        device_meter_t cpu_temp;
        device_meter_t dp_v;
        device_meter_t dn_v;
        device_meter_t power_out_v;
        device_meter_t power_out_i;
        device_meter_t power_out_p;
    };
    device_meter_t group[SRC_TABLE_METER_ITEM_NUM];
}device_meter_group_t;

typedef struct
{
    uint16_t value; // 占空比，脉冲，高低电平
    uint8_t lock; //1-锁定，0-关闭锁定
}device_out_t;

enum
{
    kDeviceOutPowerU = kBoardPWM_PowerU,
    kDeviceOutPowerI = kBoardPWM_PowerI,
};

typedef union
{
    struct
    {
        device_out_t power_v;
        device_out_t power_i;
    };
    device_out_t group[SRC_TABLE_OUT_ITEM_NUM];
}device_out_group_t;


/* 设备信息类参数 */
typedef struct
{
	char name[33]; //设备名称
	char os[28]; //操作系统，"freeRTOS10.2.0.1"
    char buildVersion[33]; //编译版本
	uint16_t svCRC; //软件校验码，156F
}device_para_info_t;

/* 设备存储类参数 */
typedef struct
{
    uint8_t pc_comm; //pc通讯
    uint8_t lcd_sleep_time; //无操作息屏时间,分钟
    uint8_t lcd_light; //屏幕亮度，10-100
    uint8_t buzzer_vol; //蜂鸣器音量，1-10
    uint8_t display_dir;//显示方向
    uint8_t pd_open_auto;//进入数控PD启动
    uint8_t pd_close_auto;//退出数控PD关闭
    uint16_t shortKey[DEVICE_SHORTKEY_NUM][2]; //快捷设置组
}device_para_store_t;

/* 设备运行类参数 */
typedef struct
{
    uint8_t power_enable; //使能电源输出
    uint16_t power_set_u; //电源电压设置 mV
    uint16_t power_set_i; //电源电压设置 mA
}device_para_run_t;

typedef struct
{
    uint8_t power_work;
    uint8_t power_mode; //0-CV, 1-CC
}device_para_status_t;
  
typedef struct
{
    device_para_store_t store;
    device_para_info_t info;
    device_para_run_t run;
    device_para_status_t status;
}device_para_t;

typedef struct
{
    map_para_t map[DEVICE_FACTOR_MAP_NUM];
    pid_para_t pid[DEVICE_FACTOR_PID_NUM];
}device_factor_t;

typedef union
{
    uint8_t value;
    struct {
        uint8_t para_store:1;
        uint8_t para_info:1;
        uint8_t para_run:1;
        uint8_t para_status:1;
        
    };
}device_change_t;

#pragma pack()

#define DEVICE_WAVE_DATA_NUM        (128)

typedef struct
{
    float value;
    float ep;
    float ei;
    float ed;
}device_wave_data_t;

typedef struct
{
    //QueueHandle_t valueQueue;
    device_wave_data_t data[DEVICE_WAVE_DATA_NUM];
    uint16_t len;        //有效长度
    uint8_t id;
    uint8_t head;
    uint8_t end;
    uint16_t interval;
    board_cnt_t cnt;
    pid_data_t *pid;
}device_wave_t;

typedef struct
{
	uint8_t mc_id[12];
    device_wave_t wave;
    device_meter_group_t meter;
    device_out_group_t out;
    device_para_t para;
    //device_factor_t factor;
    para_package_t *para_package;
    src_package_t *src_package;
    device_change_t change;
    //device_change_t ui_change;
}app_device_t;

extern device_factor_t app_dev_factor;
extern app_device_t app_dev;

extern void device_wave_init(uint8_t id, uint16_t interval);
extern uint8_t device_wave_read(uint8_t *p, uint8_t len);
extern void device_wave_cnt(void);

extern void device_pwm_out(uint8_t id, uint16_t value);
extern void device_pwm_out_test(uint8_t id, uint16_t value, uint8_t enable);

extern void app_dev_init(void);
extern void app_dev_meter_update(uint8_t id, float value);
extern void app_dev_meter_cal(uint8_t id, int32_t adc_vale);
extern void app_dev_para_init(void);
extern void device_status_refresh(void);
extern float app_dev_meter_get_max(uint8_t id);
#endif
